package com.apimarket.util.kong.impl;

import com.apimarket.entity.kong.Route;
import com.apimarket.entity.kong.Service;
import com.apimarket.enums.KongNameEnum;
import com.apimarket.exception.KongNameException;
import com.apimarket.factory.JsonMapperFactory;
import com.apimarket.util.ChineseToPinYinUtil;
import com.apimarket.util.UrlUtil;
import com.apimarket.util.kong.KongService;
import com.apimarket.util.kong.KongServiceParameters;
import com.apimarket.util.net.DeleteNetContext;
import com.apimarket.util.net.GetNetContext;
import com.apimarket.util.net.PatchJsonNetContext;
import com.apimarket.util.net.PostJsonNetContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Component
public class BaseKongService extends KongService {

    public BaseKongService() {
    }

    public BaseKongService(String baseUrl) {
        super(baseUrl);
    }

    @Override
    public Service addService(String url, String name) throws IOException, URISyntaxException {
        Map<String, Object> params = new HashMap<>();
        params.put(KongServiceParameters.SERVICE_NAME, name);
        params.put(KongServiceParameters.SERVICE_URL, url);
        UrlUtil urlUtil = new UrlUtil(new PostJsonNetContext(getBaseUrl() + addPath, params));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), Service.class);
    }

    @Override
    public Service addService(String url, String name, String id) throws IOException, URISyntaxException {
        Map<String, Object> params = new HashMap<>();
        //这里将传入的name的首字母大写组成
        //String allPinyin = ChineseToPinYinUtil.getFirstPinYin(name);
        //params.put(KongServiceParameters.SERVICE_NAME, allPinyin);
        params.put(KongServiceParameters.SERVICE_URL, url);
        params.put(KongServiceParameters.SERVICE_ID, id);
        //这里的getBaseUrl返回的是kong的admin端口url
        UrlUtil urlUtil = new UrlUtil(new PostJsonNetContext(getBaseUrl() + addPath, params));
        JsonNode root=urlUtil.getJsonRoot();
        /*try{
            root = urlUtil.getJsonRoot();
        }catch(Exception e){
            throw new KongNameException(KongNameEnum.SERVICE_NAME_ERROR);
        }*/
        //将他转为一个service对象
        return JsonMapperFactory.getInstance().readValue(root.toString(), Service.class);
    }

    @Override
    public Service getService(String nameOrId) throws IOException, URISyntaxException {
        String targetUrl = getBaseUrl() + listPath + "/" + nameOrId;
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(targetUrl, null));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), Service.class);
    }

    @Override
    public List<Service> listServices() throws IOException, URISyntaxException {
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(getBaseUrl() + listPath, null));
        JsonNode root = urlUtil.getJsonRoot();
        ObjectMapper mapper = JsonMapperFactory.getInstance();
        CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Service.class);
        return mapper.readValue(root.get("data").toString(), listType);
    }

    @Override
    public void deleteService(String nameOrId) throws IOException, URISyntaxException {
        String targetUrl = deletePath + "/" + nameOrId;
        UrlUtil urlUtil = new UrlUtil(new DeleteNetContext(getBaseUrl() + targetUrl));
        urlUtil.getJsonRoot();
    }

    //修改接口集合的方法
    @Override
    public Service updateService(Service service) throws IOException, URISyntaxException {
        String targetUrl = updatePath + "/" + service.getId();
        Map<String, Object> params = getServiceInfoMap(service);
        UrlUtil urlUtil = new UrlUtil(new PatchJsonNetContext(getBaseUrl() + targetUrl, params));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), Service.class);
    }

    @Override
    public Service updateServiceById(String id, String url) throws IOException, URISyntaxException {
        String targetUrl=updatePath+"/"+id;
        Map<String,Object> params=new HashMap<>();
        params.put(KongServiceParameters.SERVICE_URL,url);
        UrlUtil urlUtil = new UrlUtil(new PatchJsonNetContext(getBaseUrl() + targetUrl, params));
        JsonNode jsonRoot = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(jsonRoot.toString(), Service.class);
    }

    @Override
    public List<Route> listRoutesByServiceId(String id) throws IOException, URISyntaxException {
        String targetUrl=listPath+"/"+id+"/routes";
        Map<String,Object> params=new HashMap<>();
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(getBaseUrl() + targetUrl, params));
        JsonNode jsonRoot = urlUtil.getJsonRoot();
        ObjectMapper mapper = JsonMapperFactory.getInstance();
        CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Route.class);
        return mapper.readValue(jsonRoot.get("data").toString(), listType);
    }

    /**
     * 获取Service个属性值map
     */
    private Map<String, Object> getServiceInfoMap(Service service) {
        Map<String, Object> params = new HashMap<>();
        params.put(KongServiceParameters.SERVICE_ID, service.getId());
        params.put(KongServiceParameters.SERVICE_NAME, service.getName());
        params.put(KongServiceParameters.SERVICE_RETRIES, service.getRetries());
        params.put(KongServiceParameters.SERVICE_PROTOCOL, service.getProtocol());
        params.put(KongServiceParameters.SERVICE_HOST, service.getHost());
        params.put(KongServiceParameters.SERVICE_PORT, service.getPort());
        params.put(KongServiceParameters.SERVICE_PATH, service.getPath());
        params.put(KongServiceParameters.SERVICE_CONNECT_TIMEOUT, service.getConnectTimeout());
        params.put(KongServiceParameters.SERVICE_WRITE_TIMEOUT, service.getWriteTimeout());
        params.put(KongServiceParameters.SERVICE_READ_TIMEOUT, service.getReadTimeout());
        params.put(KongServiceParameters.SERVICE_TAGS, service.getTags());
        params.put(KongServiceParameters.SERVICE_CLIENT_CERTIFICATE, service.getClientCertificate());
        params.put(KongServiceParameters.SERVICE_TLS_VERIFY, service.isTlsVerify());
        params.put(KongServiceParameters.SERVICE_TLS_VERIFY_DEPTH, service.getTlsVerifyDepth());
        params.put(KongServiceParameters.SERVICE_CA_CERTIFICATES, service.getCaCertificates());
        params.entrySet().removeIf(key -> key.getValue() == null);
        return params;
    }
}
